#ifndef _FILE_CACHE_H_
#define _FILE_CACHE_H_

#include <time.h>
#include <stdio.h>
#include <dirent.h>
#include <flache.h>
#include <pthread.h>

struct file_entry_t
{
    char* path;
    char* server_path;
    char* flash_path;
    int* handles;      // an array of ints
    int handle_count;  // number of handles
    int handle_length; // length of the array
    int dirty;
    time_t time_released;
    pthread_mutex_t lock;
    pthread_mutexattr_t lock_attrib;
};

// allocates and initializes
struct file_entry_t* create_entry( char* path, int handle, struct flache_vol_t* vol );

// This method assumes you have a lock on this!
// it will unlock and free it inside
void _free_entry( struct file_entry_t* entry );

void add_handle( struct file_entry_t* entry, int handle );
void remove_handle( struct file_entry_t* entry, int handle );
int contains_handle( struct file_entry_t*, int handle );
void rename_entry( struct file_entry_t* file, const char* new_path );

void lock_entry( struct file_entry_t* entry );
void unlock_entry( struct file_entry_t* entry );

struct file_entry_list_t
{
    struct file_entry_t** entries;
    int file_count;
    int list_size;
    pthread_mutex_t lock;
    pthread_mutexattr_t lock_attrib;
};
    
struct file_entry_list_t* create_entry_list();
// frees the list and list contents; assumes you have a lock on the list
void free_entry_list( struct file_entry_list_t* entry_list ); 

void add_file( struct file_entry_list_t* list, struct file_entry_t* entry );
void remove_file( struct file_entry_list_t* list, struct file_entry_t* entry );

// this retrieves the file based on the relative path argument and LOCKS IT
struct file_entry_t* get_file( struct file_entry_list_t*, char* path );

void lock_list( struct file_entry_list_t* list );
void unlock_list( struct file_entry_list_t* list );

void print_list( FILE* file, struct file_entry_list_t* file_list );

#endif
